<template>
  <div class="document-container">
    <div class="bottom-section">
      <div class="granary-name">设置{{ granary?.name }}的数据源</div>
      <!-- Add tabs section -->
      <el-tabs v-model="activeTab" class="source-tabs">
        <el-tab-pane label="文件" name="file">
          <div class="table-header">
            <el-upload
              ref="uploadRef"
              class="upload-demo"
              :auto-upload="true"
              :show-file-list="false"
              :before-upload="beforeUpload"
              :on-success="handleUploadSuccess"
              :on-error="handleUploadError"
              :limit="1"
              :http-request="customUpload"
            >
              <el-tooltip content="上传" placement="top">
                <el-button class="upload-btn" plain>
                  <img src="@/assets/icon/more-icon.png" class="upload-icon" alt="上传" />
                </el-button>
              </el-tooltip>
            </el-upload>
          </div>

          <el-table :data="fileDocuments" style="width: 100%">
            <el-table-column type="index" label="#" width="50" />
            <el-table-column prop="filename" label="文件名">
              <template #default="scope">
                <el-tooltip
                  :content="getDocumentSummary(scope.row)"
                  placement="top-start"
                  :visible-arrow="true"
                  popper-class="summary-tooltip"
                  :enterable="true"
                  :show-after="500"
                  max-width="400"
                  :raw-content="true"
                >
                  <div class="file-name">
                    <i class="el-icon-document"></i>
                    {{ scope.row.resource.filename }}
                  </div>
                </el-tooltip>
              </template>
            </el-table-column>
            <el-table-column prop="status" label="构建状态" width="100">
              <template #default="scope">
                <el-tag :type="formatGranaryStatus(scope.row.status).type">
                  {{ formatGranaryStatus(scope.row.status).text }}
                </el-tag>
              </template>
            </el-table-column>
            <el-table-column prop="size" label="大小" width="120">
              <template #default="scope">
                {{ formatFileSize(scope.row.resource.size) }}
              </template>
            </el-table-column>
            <el-table-column prop="createTime" label="创建时间" width="180">
              <template #default="scope">
                {{ formatDate(scope.row.resource.createTime) }}
              </template>
            </el-table-column>
            <el-table-column prop="type" label="类型" width="100">
              <template #default="scope">
                <el-tag type="info">
                  {{ scope.row.resource.type }}
                </el-tag>
              </template>
            </el-table-column>
            <el-table-column label="操作" width="150">
              <template #default="scope">
                <el-tooltip content="删除" placement="top">
                  <el-button class="delete-btn" type="text" @click="handleFileDelete(scope.row.docUrn)">
                    <img src="@/assets/icon/delete.png" class="delete-icon" alt="删除" />
                  </el-button>
                </el-tooltip>
              </template>
            </el-table-column>
          </el-table>
        </el-tab-pane>

        <el-tab-pane label="网页" name="webpage">
          <div class="table-header">
            <el-tooltip content="添加" placement="top">
              <el-button class="upload-btn" plain @click="showUrlDialog">
                <img src="@/assets/icon/more-icon.png" class="upload-icon" alt="添加" />
              </el-button>
            </el-tooltip>
          </div>

          <el-table :data="webDocuments" style="width: 100%">
            <el-table-column type="index" label="#" width="50" />
            <el-table-column prop="externalLink" label="链接" width="220">
              <template #default="scope">
                <el-tag type="info">
                  {{ scope.row.resource.externalLink }}
                </el-tag>
              </template>
            </el-table-column>
            <el-table-column prop="filename" label="文件名" width="200">
              <template #default="scope">
                <el-tooltip
                  :content="getDocumentSummary(scope.row)"
                  placement="top-start"
                  :visible-arrow="true"
                  popper-class="summary-tooltip"
                  :enterable="true"
                  :show-after="500"
                  max-width="400"
                  :raw-content="true"
                >
                  <div class="file-name">
                    <i class="el-icon-document"></i>
                    {{ scope.row.resource.filename }}
                  </div>
                </el-tooltip>
              </template>
            </el-table-column>
            <el-table-column prop="status" label="构建状态" width="100">
              <template #default="scope">
                <el-tag :type="formatGranaryStatus(scope.row.status).type">
                  {{ formatGranaryStatus(scope.row.status).text }}
                </el-tag>
              </template>
            </el-table-column>
            <el-table-column prop="createTime" label="创建时间" width="180">
              <template #default="scope">
                {{ formatDate(scope.row.resource.createTime) }}
              </template>
            </el-table-column>
            <el-table-column label="操作" width="150">
              <template #default="scope">
                <el-tooltip content="删除" placement="top">
                  <el-button class="delete-btn" type="text" @click="handleWebpageDelete(scope.row.docUrn)">
                    <img src="@/assets/icon/delete.png" class="delete-icon" alt="删除" />
                  </el-button>
                </el-tooltip>
              </template>
            </el-table-column>
          </el-table>
        </el-tab-pane>

        <el-tab-pane label="网盘" name="cloud">
          <!-- Cloud storage content to be implemented -->
          <div class="empty-state">
            功能开发中...
          </div>
        </el-tab-pane>
      </el-tabs>
      <div class="form-footer">
        <el-button type="primary" @click="saveGranary" class="primary-button">
          保存
        </el-button>
      </div>
    </div>

    <!-- Add URL dialog -->
    <el-dialog
      v-model="urlDialogVisible"
      title="添加网页"
      width="500px"
    >
      <el-button 
        type="text" 
        @click="addUrlEntry" 
        class="dialog-add-btn"
      >
        <img src="@/assets/icon/more-icon.png" alt="添加" class="small-icon" />
      </el-button>
      <el-form :model="urlForm" ref="urlFormRef">
        <div v-for="(entry, index) in urlForm.urlEntries" :key="index" class="url-entry">
          <el-form-item
            :prop="`urlEntries.${index}.url`"
            :rules="[{ required: true, message: '请输入URL地址', trigger: 'blur' }]"
          >
            <el-input v-model="urlForm.urlEntries[index].url" placeholder="http://www.example.com" />
          </el-form-item>
          <el-form-item
            :prop="`urlEntries.${index}.alias`"
          >
            <el-input v-model="urlForm.urlEntries[index].alias" placeholder="别名" />
          </el-form-item>
          <el-button 
            type="text" 
            @click="removeUrlEntry(index)"
            class="delete-url-btn"
            v-if="urlForm.urlEntries.length > 1"
          >
            <img src="@/assets/icon/delete.png" alt="删除" class="small-icon" />
          </el-button>
        </div>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button type="primary" @click="handleUrlSubmit">完成</el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted } from 'vue'
import { ElMessage } from 'element-plus'
import { useRouter, useRoute } from 'vue-router'
import { useUserStore } from '@/store/user'
import { GetGranaryRequest,ListGranariesRequest,ListGranariesResponse, Granary } from '@/types/proto/api/v1/granary_service'
import { Resource, GetResourceRequest, CreateResourceRequest } from '@/types/proto/api/v1/resource_service'
import { ListResources, GetResource, CreateResource } from "@/api/resource";
import { GetGranary, CreateGranary, UpdateGranary, CtrlGranary, ListGranaryResources } from "@/api/granary";
import { CreateGranaryRequest, UpdateGranaryRequest, CtrlGranaryRequest, GranaryCmd, GranaryStatus} from '@/types/proto/api/v1/granary_service'
import { ListGranaryResourcesRequest, ListGranaryResourcesResponse,GranaryResourcecState } from '@/types/proto/api/v1/granary_service'
import { formatGranaryStatus } from "@/api/granary";
import { ListModels } from "@/api/llm";
import { LLMModel,ListLLMModelResponse } from '@/types/proto/api/v1/llm_service'
import { formatFileSize, formatDate } from '@/utils/resource'
// import startIcon from '@/assets/icon/start.png'
// import stopIcon from '@/assets/icon/stop.png'

// const documents = ref<Resource[]>([])
const userStore = useUserStore()
const granary = ref<Granary | null>(null)
const llmModels = ref<LLMModel[]>([])
const isRunning = ref(false)

const buildTypeOptions = [
  { value: 'graph', label: '知识图谱' },
  { value: 'summary', label: '知识总结' }
]

interface GranaryForm {
  name: string
  description: string
  avatar: string
  tags: string[]
  options: string[]
  sources: string[]
  currentGranay: Granary|null,
  llmModel: string
  embeddingModel: string
}

const granaryForm = ref<GranaryForm>({
  name: '',
  description: '',
  avatar: '',
  tags: [],
  options: [],
  sources: [],
  currentGranay: null,
  llmModel: '',
  embeddingModel: ''
})

const fileInput = ref<HTMLInputElement | null>(null)

// Add URL-related refs and functions
const urlDialogVisible = ref(false)
const urlForm = ref({
  urlEntries: [{ url: '', alias: '' }]
})
const urlFormRef = ref()

// Add new refs for tabs
const activeTab = ref('file')
const fileDocuments = ref<GranaryResourcecState[]>([])
const webDocuments = ref<GranaryResourcecState[]>([])

// Add this ref at the top with other refs
const uploadRef = ref()

const loadDocuments = async () => {
  console.log("doc load documents")
  if (granary.value != null) {
    console.log("doc load documents granary not null")
    fileDocuments.value = []
    webDocuments.value = []
    let res =await ListGranaryResources({urn:granary.value.urn})
    for (const resource of res.resources) {
      let r=resource.resource
      if (r==null) {
        continue
      } 

      if (r.type === 'LINK') {
        webDocuments.value.push(resource)
      } else {
        fileDocuments.value.push(resource)
      }
    }
  }
}
const router = useRouter()
const route = useRoute()

const parseParamFromRoute = async () => {
  try {
      console.log("doc parse param")
      const urn = route.query.granary
      let reload = true
      console.log("doc granary urn:", urn)
      if (urn === null || urn === undefined) {
          granary.value = null
          reload = false
      } else if (granary.value != null) {
          if (granary.value.urn === urn) {
              console.log("no need to reload")
              reload = false
          }
      }

      if (reload) {
          console.log("doc reload granary")
          let req = {urn:urn} as GetGranaryRequest
          let res = await GetGranary(req)
          granary.value = res
      }

      userStore.granary = granary.value
      if (granary.value != null) {
        granaryForm.value.currentGranay = JSON.parse(JSON.stringify(granary.value))
        granaryForm.value.sources = granary.value.sources
        granaryForm.value.name = granary.value.name
        granaryForm.value.description = granary.value.description
        granaryForm.value.avatar = granary.value.avatar
        granaryForm.value.tags = granary.value.tags
        granaryForm.value.options = Object.entries(granary.value.options)
          .filter(([_, value]) => value === 'true')
          .map(([key]) => key)
        granaryForm.value.llmModel = granary.value.llmModel
        granaryForm.value.embeddingModel = granary.value.embeddingModel
        console.log("doc parse param granaryForm", granaryForm.value)
        switch (granary.value.status) {
          case GranaryStatus.CHUNKING:
          case GranaryStatus.GRAPHING:
          case GranaryStatus.SUMMARIZING:
          case GranaryStatus.STARTING:
            isRunning.value = true
            break
          default:
            isRunning.value = false
            break
        }
      }
  } catch (error) {
      console.error('Error parsing document from route:', error)
  }
}

const loadModels = () => {
  console.log("doc load models")
  const pageToken = { limit: 1000, offset: 0 }
  const filter = ""
  ListModels({ pageSize: 1000, pageToken, filter: filter }).then((res:ListLLMModelResponse)=>{
    llmModels.value = res.models
  }).catch(error => {
      console.error('Failed to fetch news:', error)
  })
}

// const formatFileSize = (bytes: number) => {
//   if (bytes === 0) return '0 B';
//   const k = 1024;
//   const sizes = ['B', 'KB', 'MB', 'GB'];
//   const i = Math.floor(Math.log(bytes) / Math.log(k));
//   return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
// }


// const formatDate = (date: Date | undefined) => {
//   if (!date) return '';
//   return new Date(date).toLocaleString();
// }

const MAX_FILE_SIZE = 100 * 1024 * 1024; // 100MB

const beforeUpload = (file: File) => {
  if (file.size > MAX_FILE_SIZE) {
    ElMessage.error('文件大小不能超过100MB')
    return false
  }
  return true
}

const customUpload = async (options: any) => {
  try {
    const file = options.file
    const fileContent = new Uint8Array(await file.arrayBuffer())
    console.log("doc custom upload file", file)
    let req = {
      filename: file.name, 
      type: file.type,
      content: fileContent
    } as CreateResourceRequest
    console.log("doc custom upload req", req)
    
    let res = await CreateResource(req)
    console.log("doc custom upload res", res)
    console.log("doc handle upload success", res)
    if (res == null) {
      return
    } 
    let r = {docUrn:res.urn, resource:res} as GranaryResourcecState
    fileDocuments.value.push(r)
    granaryForm.value.sources.push(res.urn)
    options.onSuccess()
  } catch (error) {
    console.error('Error uploading file:', error)
    options.onError(error)
  }
}

const handleUploadSuccess = () => {
  ElMessage.success('文件上传成功')
  // Reset the upload component
  uploadRef.value?.clearFiles()
}

const handleUploadError = (error: any) => {
  console.error('Error uploading file:', error)
  ElMessage.error('文件上传失败')
}

const showUrlDialog = () => {
  urlDialogVisible.value = true
}

const addUrlEntry = () => {
  urlForm.value.urlEntries.push({ url: '', alias: '' })
}

const removeUrlEntry = (index: number) => {
  urlForm.value.urlEntries.splice(index, 1)
}

const handleUrlSubmit = async () => {
  if (!urlFormRef.value) return
  
  await urlFormRef.value.validate(async (valid: boolean) => {
    if (valid) {
      try {
        for (const entry of urlForm.value.urlEntries) {
          console.log('Submitted URL:', entry.url, 'Alias:', entry.alias)
          
          // 创建资源请求
          let req = {
            filename: entry.alias || entry.url,
            type: 'LINK',
            externalLink: entry.url
          } as CreateResourceRequest
          
          let res = await CreateResource(req)
          let r = {docUrn:res.urn, resource:res} as GranaryResourcecState
          webDocuments.value.push(r)
          granaryForm.value.sources.push(res.urn)
        }
        
        ElMessage.success('网页添加成功')
        urlDialogVisible.value = false
        urlForm.value.urlEntries = [{ url: '', alias: '' }]
      } catch (error) {
        console.error('Error adding URL:', error)
        ElMessage.error('网页添加失败')
      }
    }
  })
}

const saveGranary = async () => {
  try {
    if (granaryForm.value.currentGranay) {
      // Update existing granary
      let g={...granaryForm.value.currentGranay}
      let updateMask=[]
      console.log("doc save granary form sources", granaryForm.value.sources)
      console.log("doc save granary sources", g.sources)
      if (g.sources != granaryForm.value.sources) {
        g.sources = granaryForm.value.sources
        updateMask.push("sources")
      }
      console.log("doc save granary updateMask", updateMask)
      
      let req={granary:g, updateMask:updateMask} as UpdateGranaryRequest

      const res = await UpdateGranary(req)
      granary.value = res
      ElMessage.success('知识库更新成功')
    } else {
      ElMessage.error('先创建知识库')
    }
  } catch (error) {
    console.error('Error saving granary:', error)
    ElMessage.error('保存失败')
  }
}

const handleFileDelete = (urn: string) => {
  const index = granaryForm.value.sources.findIndex(item => item === urn)
  if (index !== -1) {
    granaryForm.value.sources.splice(index, 1)
  }
  fileDocuments.value = fileDocuments.value.filter(item => item.docUrn !== urn)
}

const handleWebpageDelete = (urn: string) => {
  const index = granaryForm.value.sources.findIndex(item => item === urn)
  if (index !== -1) {
    granaryForm.value.sources.splice(index, 1)
  }
  webDocuments.value = webDocuments.value.filter(item => item.docUrn !== urn)
}

const getDocumentSummary = (document: GranaryResourcecState) => {
  if (!document || !document.resource) return '暂无摘要信息';
  
  let summaryText = document.summary || '暂无摘要';
  
  // 添加样式到内联HTML中以控制宽度和换行
  return `<div class="summary-content" style="width: 380px; max-width: 380px;">
            <div class="summary-title" style="font-weight: bold; margin-bottom: 4px;">摘要:</div>
            <div class="summary-text" style="line-height: 1.4; margin-bottom: 8px; white-space: normal; word-break: break-word; overflow-wrap: break-word;">
              ${summaryText}
            </div>
            <div class="summary-title mt-2" style="font-weight: bold; margin-top: 8px; margin-bottom: 4px;">关键词:</div>
            <div class="tags-container" style="display: flex; flex-wrap: wrap; gap: 4px;">
              ${formatTags(document.tags)}
            </div>
          </div>`;
}

const formatTags = (tags: string[] | undefined) => {
  if (!tags || tags.length === 0) return '暂无关键词';
  
  return tags.map(tag => `<span class="tag-item">${tag}</span>`).join('  ');
}

onMounted(() => {
  console.log("doc on mounted")
  if (userStore.granary != null) {
    granary.value = userStore.granary
  }

  parseParamFromRoute().then(() => {
    loadDocuments()
    loadModels()
  })
})

</script>

<style scoped lang="scss">
.document-container {
  padding: 20px;
  display: flex;
  flex-direction: column;
  gap: 24px;
}

.top-section {
  display: flex;
  gap: 24px;
  min-height: 400px;
}

.info-panel {
  flex: 1;
  background: #fff;
  border-radius: 4px;
  border: 1px solid #e4e7ed;
  padding: 20px;
}

.form-content {
  margin-top: 20px;
}

.summary-panel {
  width: 400px;
  background: #fff;
  border-radius: 4px;
  border: 1px solid #e4e7ed;
  padding: 20px;
  display: flex;
  flex-direction: column;
}

.summary-header {
  margin-bottom: 16px;
  border-bottom: 1px solid #e4e7ed;
  padding-bottom: 8px;

  h3 {
    margin: 0;
    font-size: 16px;
    color: #303133;
  }
}

.summary-content {
  flex: 1;
  overflow-y: auto;
}

.summary-text {
  font-size: 14px;
  line-height: 1.6;
  color: #606266;
  white-space: pre-wrap;
}

.empty-summary {
  color: #909399;
  text-align: center;
  padding: 40px 0;
}

.bottom-section {
  background: #fff;
  border-radius: 4px;
  border: 1px solid #e4e7ed;
  padding: 20px;
}

.name-input {
  font-size: 20px;
  font-weight: bold;
  
  :deep(.el-input__inner) {
    border: none;
    padding: 0;
    
    &:focus {
      border: 1px solid #dcdfe6;
      padding: 0 8px;
    }
  }
}

.model-select {
  width: 100%;
}

.granary-header {
  display: flex;
  align-items: center;
  gap: 16px;
  margin-bottom: 24px;
}

.granary-title {
  flex: 1;
  
  .el-form-item {
    margin-bottom: 0;
  }

  .name-input {
    margin-bottom: 0;
    
    :deep(.el-input__wrapper) {
      padding-top: 0;
      padding-bottom: 0;
    }
  }
}

.granary-tags {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;

  .tag {
    margin-right: 4px;
  }
}

.divider {
  height: 1px;
  background-color: #e4e7ed;
  margin: 16px 0;
}

.sub-description {
  margin: 8px 0 16px;
}

.search-bar {
  display: flex;
  gap: 16px;
  margin-bottom: 20px;
}

.add-button {
  white-space: nowrap;
}

.file-name {
  display: flex;
  align-items: center;
  gap: 8px;
}

.el-dropdown-link {
  cursor: pointer;
  margin-left: 12px;
}

.name-section, .description-section, .build-types {
  display: flex;
  align-items: flex-start;
  
  .label {
    color: #606266;
    width: 70px;
    flex-shrink: 0;
    text-align: left;
    white-space: nowrap;
  }
}

.name-section {
  .name-input {
    flex: 1;
  }
}

.description-section {
  .description-input {
    flex: 1;
  }
}

.build-types {
  align-items: center;
  
  .el-checkbox-group {
    flex: 1;
  }
}

.table-header {
  display: flex;
  justify-content: flex-end;
  gap: 12px;
  margin-bottom: 16px;
  padding-right: 20px;
}

.upload-btn {
  padding: 8px;
  height: auto;
  background: rgba(0, 0, 0, 0.04);
  border: none;
  
  &:hover {
    background: rgba(0, 0, 0, 0.08);
  }
}

.upload-icon {
  width: 20px;
  height: 20px;
  vertical-align: middle;
}

.delete-btn {
  margin-left: 12px;
  padding: 4px;
}

.delete-icon {
  width: 16px;
  height: 16px;
  vertical-align: middle;
}

.action-buttons {
  margin-top: 16px;
  display: flex;
  justify-content: flex-end;
}

.form-row {
  display: flex;
  align-items: center;
  gap: 20px;
}

.name-container {
  flex: 1;
  margin: 0;
}

.avatar-uploader {
  border: 1px dashed #d9d9d9;
  border-radius: 6px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
  width: 30px;
  height: 30px;
  display: flex;
  justify-content: center;
  align-items: center;
  flex-shrink: 0;

  &:hover {
    border-color: var(--el-color-primary);
  }
}

.avatar {
  width: 30px;
  height: 30px;
  border-radius: 50%;
  display: block;
}

.default-avatar {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.avatar-uploader-icon {
  font-size: 28px;
  color: #8c939d;
  width: 64px;
  height: 64px;
  display: flex;
  justify-content: center;
  align-items: center;
}

.el-avatar {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.full-width {
  width: 100%;
}

.full-width :deep(.el-input),
.full-width :deep(.el-select),
.full-width :deep(.el-textarea) {
  width: 100%;
}

.name-container {
  flex: 1;
}

.name-input {
  width: 100%;
}

.description-input {
  width: 100%;
}

.model-select {
  width: 100%;
}

.save-btn,
.control-btn {
  margin-left: 8px;
  padding: 8px;
  height: 32px;
  width: 32px;
}

.save-icon,
.control-icon {
  width: 16px;
  height: 16px;
}

.start-btn {
  &:hover {
    color: #67C23A;
    border-color: #67C23A;
  }
}

.stop-btn {
  &:hover {
    color: #F56C6C;
    border-color: #F56C6C;
  }
}

.granary-status {
  margin-top: 16px;
}

// Add URL dialog styles
.dialog-footer {
  display: flex;
  justify-content: flex-end;
  gap: 12px;
}

.url-entry {
  display: flex;
  align-items: center;
  gap: 16px;

  .el-form-item {
    flex: 1;
    margin-bottom: 18px;
  }

  .delete-url-btn {
    padding: 0;
    margin-bottom: 18px;
    
    .small-icon {
      width: 16px;
      height: 16px;
    }
  }
}

.small-icon {
  width: 24px;
  height: 24px;
}

.dialog-add-btn {
  position: absolute;
  right: 45px;
  top: 25px;
  padding: 0;
}

.source-tabs {
  margin-bottom: 20px;
}

.empty-state {
  text-align: center;
  padding: 40px;
  color: #909399;
  font-size: 14px;
}

.upload-demo {
  display: inline-block;
}

.summary-tooltip {
  max-width: 400px !important;
  
  :deep(.el-popper) {
    max-width: 400px !important;
    width: 400px !important;
  }
  
  :deep(.el-tooltip__popper) {
    max-width: 400px !important;
    width: 400px !important;
  }
  
  :deep(.el-popper__content) {
    max-width: 400px !important;
    width: 400px !important;
    word-break: break-word !important;
    white-space: normal !important;
  }
}

.summary-content {
  padding: 8px;
  width: 100%;
}

.summary-title {
  font-weight: bold;
  margin-bottom: 4px;
}

.summary-text {
  line-height: 1.4;
  margin-bottom: 8px;
  white-space: pre-wrap;
  word-wrap: break-word;
  word-break: break-word;
  max-width: 380px;
}

.tags-container {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  max-width: 380px;
}

.tag-item {
  background-color: #f0f0f0;
  padding: 2px 6px;
  border-radius: 4px;
  font-size: 12px;
}

.mt-2 {
  margin-top: 8px;
}
</style>
